// onjava/Suppliers.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// A utility to use with Suppliers
package onjava;

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

/**
 * 
 * 工具：创建并填充集合
 *
 * @author Lucky Yang
 */
public class Suppliers {

  /**
   * Create a collection and fill it:
   * <br>
   * 
   * 创建集合并填充
   * 
   * @param <T> 填充类型
   * @param <C> 集合类型
   * @param factory 创建集合工厂
   * @param gen 填充对象生成器
   * @param n 填充对象生成数量
   * @return
   */
  public static <T, C extends Collection<T>> C create(Supplier<C> factory, Supplier<T> gen, int n) {
    return Stream.generate(gen)
        .limit(n)
        .collect(factory, C::add, C::addAll);
  }

  /**
   * Fill an existing collection:
   * <br>
   * 
   * 填充已有的集合
   * 
   * @param <T> 填充类型
   * @param <C> 集合类型
   * @param coll 集合对象
   * @param gen 填充对象生成器
   * @param n 填充对象生成数量
   * @return
   */
  public static <T, C extends Collection<T>> C fill(C coll, Supplier<T> gen, int n) {
    Stream.generate(gen)
        .limit(n)
        .forEach(coll::add);
    return coll;
  }

  /**
   * Use an unbound method reference to produce a more general method:
   * 
   * @param <H>
   * @param <A>
   * @param holder
   * @param adder
   * @param gen
   * @param n
   * @return
   */
  public static <H, A> H fill(H holder,
      BiConsumer<H, A> adder, Supplier<A> gen, int n) {
    Stream.generate(gen)
        .limit(n)
        .forEach(a -> adder.accept(holder, a));
    return holder;
  }
}
